Introduzione
Abstract
Lo studio delle serie storiche riguardanti il Prodotto Interno Lordo (PIL) della Gran Bretagna rappresenta un’importante analisi economica volta a comprendere l’evoluzione e le dinamiche dell’economia britannica nel corso del tempo.
Il PIL è uno degli indicatori chiave per valutare la salute economica di un paese e fornisce una misura del valore totale dei beni e dei servizi prodotti all’interno di un’area geografica specifica. Esaminando la serie storica del PIL britannico, siamo in grado di analizzare le tendenze, gli eventi significativi e le fluttuazioni economiche che hanno caratterizzato il Regno Unito nel corso dei decenni.
L’obiettivo di questo studio è quello di esplorare e comprendere l’andamento del PIL britannico nel corso della storia recente, per poi proseguire con la costruzione di un modello previsivo avvalendoci di altre serie storiche macroeconomiche.
I dati
Per la mia ricerca, ho scelto di utilizzare il sito Fred come fonte primaria per l’acquisizione delle serie storiche, un vasto archivio di dati gestito dalla Federal Reserve Banking of St.Louis. Le serie storiche individuate per l’analisi sono trimestrali, non destagionalizzate e che coprono un periodo di tempo specifico: dal primo trimestre del 1998 al quarto trimestre del 2022.
La scelta del periodo di analisi è stata fatta per ottenere una visione ampia dell’evoluzione del PIL britannico nel corso degli ultimi anni. Questo intervallo temporale ci permette di catturare cambiamenti significativi nell’economia britannica dovuti, per esempio, ad eventi politici importanti come la BREXIT, la crisi finanziaria del 2008 o alla pandemia globale di COVID-19.
Real GDP for Great Britain
Come anticipiato, la serie principale in analisi è il Real Gross Domestic Product della Gran Bretannia, denominato in italiano con PIL, acronimo di ‘Prodotto interno lordo’.
gdp_dat <- read_excel("NGDPRNSAXDCGBQ.xls",
col_types = c("date", "numeric"), skip = 10)
gdp <- ts(gdp_dat$NGDPRNSAXDCGBQ,start = c(1998),frequency = 4)
Fonte:
International Monetary Fund, Real Gross Domestic Product for Great Britain [NGDPRNSAXDCGBQ], retrieved from FRED, Federal Reserve Bank of St. Louis;
https://fred.stlouisfed.org/series/NGDPRNSAXDCGBQ, June 20, 2023.
dyRangeSelector((dygraph(gdp,
main = 'Real Gross Domestic Product',
ylab = 'Domestic Currency(£)') %>%
dyEvent(c('2020-04-01','2009-04-01'),
c('Covid-19', 'Crisi Finanziaria 2008'),
labelLoc ='bottom',strokePattern = 'dotted',color = 'red') %>%
dyEvent('2020-01-01','Brexit',labelLoc ='top',
strokePattern = 'dotted',color = 'red')))
Nel complesso possiamo dire che il trend del GDP inglese è abbastanza crescente.
Da una prima analisi possiamo notare una crescita moderata, ma costante, del trend fino al 2008, anno in cui si assiste ad una rapida descrescita causata dalla crisi finanziaria del 2007-2008. In seguito, si nota un nuovo rialzo fino alla prima metà del 2020, anno in cui a causa della Brexit prima, e alla pandemia Covid-19 dopo, si assiste a una nuova fase decrescente del trend. Soprattutto quest’ultima ha avuto effetti drammatici sull’economia globale; nonostante ciò il GDP inglese non ha raggiunto i minimi storici.
Brexit
Tra i fattori che hanno influenzato le variazioni del GDP inglese, la Brexit in paricolare, a differenza delle cause sopracitate, non ha avuto ripercursioni eccessivamente tangibili sugli altri Paesi, mentre ha influito particolarmente sul territorio britannico.
In seguito sono riportate le parole di Richard Hughes presidente dell’Office for Budget Responsibility, un’agenzia pubblica finanziata dal ministero del Tesoro del Regno Unito, riguardante la Brexit: “è uno shock per l’economia del Regno Unito dell’ordine di grandezza del tipo di altri shock che abbiamo visto, dalla pandemia alla crisi energetica”.
Il Regno Unito ha votato per lasciare l’UE nel 2016 ed è uscito formalmente dall’Unione nel gennaio 2020. L’uscita ha reso più difficile per alcune aziende trovare lavoratori (vedere serie storica sul numero di lavoratori) e piu complicato per i produttori nazionali vendere merci nell’UE (vedere serie storica sulle esportazioni). Inoltre, l’avvenuta della Brexit in un anno caratterizzato dalla pandemia, rende difficile fare un bilancio sull’impatto della Brexit sul PIL nazionale.
Proprio per questo motivo partirò con la pulizia della serie storica provando, quindi, ad eliminare quei valori anomali dovuti dalla pandemia.
Pulizia dei dati
- Missing values : Innanzitutto verifico la presenza di Na all’interno della serie storica
knitr::kable(ifelse(anyNA(gdp) == 'FALSE',0,1),,col.names = 'Missing Values')
| Missing Values |
|---|
| 0 |
- Outliers : per gli outliers uso il comando tsoutliers del pacchetto forecast
tsoutliers(gdp)
## $index
## [1] 88 90 91 92 93
##
## $replacements
## [1] 565099.1 542922.2 545616.9 554525.6 534595.4
La serie storica in analisi presenta 5 possibili outliers, vediamo quali sono.
knitr::kable(gdp_dat[c(88,90,91,92,93),],col.names = c('Date','GDP'))
| Date | GDP |
|---|---|
| 2019-10-01 | 579989 |
| 2020-04-01 | 426079 |
| 2020-07-01 | 495712 |
| 2020-10-01 | 524758 |
| 2021-01-01 | 497091 |
Come possiamo notare, la finestra temporale dei valori anomali coincide con quella della pandemia Covid-19. Stando ai dati possiamo notare che nell’ultimo trimestre del 2020 c’è stata una leggera ripresa rispetto al picco del secondo trimestre dello stesso anno. La fase di crescita reale c’è stata solo dopo il secondo trimestre dell’anno successivo. Si nota che il periodo relativo alla crisi finanziaria non presenta valori anomali nella serie.
Ora posso creare una nuova serie storica in cui rimpiazzo gli outliers dovuti alla pandemia attraverso la decomposizione robusta STL. Per la creazione utilizzo la funzione tsclean.
gdp_noCovid <- tsclean(gdp)
data <- gdp_dat[c(88,90,91,92,93),1]
data$GDP_NoCovid <- gdp_noCovid[c(88,90,91,92,93)]
knitr::kable(data, col.names = c('Date', 'GDP_NoCovid'))
| Date | GDP_NoCovid |
|---|---|
| 2019-10-01 | 565099.1 |
| 2020-04-01 | 542922.2 |
| 2020-07-01 | 545616.9 |
| 2020-10-01 | 554525.6 |
| 2021-01-01 | 534595.4 |
come possiamo notare i valori anomali sono stati sostituiti con quelli ottenuti precedentemente con la funzione tsoutliers.
Ora confronto le due serie attraverso un’analisi empirica
autoplot(gdp_noCovid, series="No Covid") +
autolayer(gdp, series="Real") +
ggtitle("Confronto tra le due serie storiche") +
xlab("Year") +
ylab("Domestic Currency (£)") +
guides(colour=guide_legend(title="Time Series"))
Porterò, in seguito, le analisi contemporaneamente per le due serie storiche, partendo con lo studio della stagionalità.
Stagionalità
Per stagionalità intendiamo fluttuazioni economiche che si ripetono regolarmente nel tempo. Le fluttuazioni stagionali possono avere un impatto sul PIL, poichè portano a variazioni nel volume di produzione, nella domanda e offerta di bene e servizi.
Durante i periodi di alta stagionalità, il PIL può registrare un aumento a causa di una maggiore attività economica, mentre nei periodi di bassa stagionalità, potrebbe verificarsi una diminuzione dell’attività economica. Pertanto, per ottenere una valutazione accurata dell’andamento del GDP britannico, occorre utilizzare tecniche di correzione stagionale ai dati. Questo processo consente di isolare l’effetto della stagionalità permettendo, quindi, di scovare variazioni dell’attività economica dovute da altri fattori.
Prima però verifico la presenza della stagionalità nella serie.
- GDP with covid-19
ggseasonplot(gdp,year.labels.left = TRUE, year.label = TRUE) +
ylab('Domestic Currency(£)') +
ggtitle('Seasonal plot GDP with Covid-19 outliers')
ggsubseriesplot(gdp)+
ylab('Domestic Currency(£)') +
ggtitle('Seasonal subseries plot GDP with Covid-19 outliers')
Nel complesso possiamo dire che la stagionalità influenza la serie, sebbene non in maniera evidente. I due grafici in analisi raggruppano le osservazioni per ogni trimestre, in blu nel subseries plot abbiamo i valori medi del GDP per ognuno di essi. Quest’ultimi non sembrano essere così diversi tra loro ad eccezione del secondo e quarto trimestre, in cui vi è una variazione di quasi 50000 £. Notiamo, inoltre, la presenza di trend crescente poichè i valori medi crescono da trimestre a trimestre. Per quanto riguarda il Seasonal Plot, notiamo ancora anomalie nell’anno 2020, in cui la serie non rispetta la stagionalità come negli altri anni. A partire dal 2010 notiamo una minima crescita del GDP nel primo trimestre, mentre negli anni precedenti esso era in decrescita. La variazione maggiore nel primo trimestre si è avuta nel 2014 in senso positivo e nel 2020 in senso negativo. Sempre nello stesso anno notiamo un crescita elevata tra il secondo semestre e terzo trimestre.
Osseviamo la stagionalità per la serie senza i valori anomali.
- GDP without covid-19
ggseasonplot(gdp_noCovid,year.labels.left = TRUE, year.label = TRUE) +
ylab('Domestic Currency(£)') +
ggtitle('Seasonal plot GDP without Covid-19 outliers')
ggsubseriesplot(gdp_noCovid)+
ylab('Domestic Currency(£)') +
ggtitle('Seasonal subseries plot GDP without Covid-19 outliers')
Eliminando i valori anomali, non ritroviamo più il picco negativo nell’anno 2020. Nel complesso posso confermare quanto detto precedentemente.
Data la presenza di trend e stagionalità possiamo dire che la serie non è stazionaria. Pertanto verifichiamo l’autocorrelazione.
Autocovarianza e Autocorrelazione
L’autocovarianza misura la presenza di legame lineare tra due punti della stessa serie storica osservati in momenti diversi. Essa può essere calcolata per diverse distanze temporali ed è definita come
\(\hat{y}(h) = \frac{1}{T} \sum_{t = 1}^{T-h} (x_{t+h}- \overline{x}) (x_t - \overline{x})\)
dove \(h = 0,1,\dots,M\) sta per il ritardo e \(\overline{x}\) la media campionaria della serie. Siccome \(\hat{y}(h) = \hat{y}(-h)\), quindi simmetrica, possiamo calcolarla soltanto per valori positivi di h.
Un valore di autocovarianza positivo indica una correlazione positiva mentre un valore negativo indica una correlazione negativa. Un valore di autocovarianza vicino a zero indica una bassa correlazione tra le osservazioni.
Per capire quanto è forte il legame lineare si guarda all’autocorrelazione.
L’autocorrelazione misura la forza del legame lineare tra due punti della stessa serie storica osservati in momenti diversi. Essa è definita come \(\hat{\rho}(h) = \frac{\hat{\gamma}(h)}{\hat{\gamma}(0)}\). Anche \(\hat{\rho}(h)\) è simmetrica positiva pertanto possiamo calcolare solo la metà positiva L’ACF(autocorrelazione campionaria) misura quanto la serie al tempo t riesca a prevedere attraverso una relazione lineare la stessa serie al tempo t+h, ovvero \(\hat{\rho}(h) = 1 \to x_{t+h} = \beta_{0} + \beta_{1}*x_{t}\)
ggAcf(gdp, plot = FALSE)
##
## Autocorrelations of series 'gdp', by lag
##
## 0 1 2 3 4 5 6 7 8 9 10 11 12
## 1.000 0.901 0.825 0.806 0.779 0.708 0.649 0.643 0.651 0.603 0.567 0.592 0.587
## 13 14 15 16 17 18 19 20
## 0.531 0.480 0.465 0.450 0.399 0.349 0.332 0.321
ggAcf(gdp)
Al ritardo 1 abbiamo l’autocorrelazione più alta in assoluto, questo significa che attraverso un modello lineare è possibile prevedere la serie storica al tempo t + 1 prendendo come covariata la stessa serie al tempo t. Come possiamo osservare, la serie storica è fortemente caratterizzata dal trend in quanto le autocorrelazioni sono molto vicine tra loro e diminuiscono gradualmente all’aumentare di h. Anche in questo caso possiamo individuare una scarsa stagionalità nei dati anche perchè le autocorrelazioni sembrano aumentare di poco a multipli della frequenza stagionale, almeno fino al ritardo 12. Inoltre per valori elevati di h, le autocorrelazioni sembrano comunque essere distanti dall’intervallo di confidenza che designa una serie storica white noise.
A questo punto, anche se la risposta sembrerebbe scontata dalle analisi svolte sino ad ora, procedo con l’eseguire una Decomposizione della serie per capire quale componente la influenzi maggiormente.
Decomposizione
Vogliamo isolare le componenti dalla serie con l’obiettivo di trovare altri fattori che influenzano la serie storica. Si procede con la decomposizione STL(Seasonal and Trend decomposition using Loess), in quanto la Loess è molto robusta a valori anomali.
gdp_stl <- stl(ts(as.vector(gdp), start=1998, frequency = 4), s.window = "periodic", robust=TRUE)
autoplot(gdp_stl)
Più la dimensione delle barrette alla destra di ogni componente è vicina a quella dei dati, più la componente è importante nello spiegare l’evoluzione della serie. In questo caso la componente principale è quella di trend, come già ci aspettavamo.
Notiamo che sia i dati, che i residui sono ancora influenzati dagli outliers dovuti alla pandemia Covid-19, nonostante abbia utilizzato la decomposizione robusta STL. Procendo, dunque, ad applicare la decomposizione alla serie GDP without Covid-19
gdp_noCovid_stl <- stl(ts(as.vector(gdp_noCovid), start=1998, frequency = 4), s.window = "periodic", robust=TRUE)
autoplot(gdp_noCovid_stl)
Anche in questo caso la componente di trend risulta quella principale, mentre notiamo una componente dei residui che è meno influente sulla serie. Questo perchè abbiamo eliminato i valori anomali che influenzavano sia i residui che la serie storica che generavano una sorta di dipendenza tra le due distribuzioni.
Non ci resta che dare un valore che testimoni la forza delle componenti di trend e stagionalità.
var_R <- var(gdp_noCovid_stl$time.series[,3])
var_trend <- var(gdp_noCovid_stl$time.series[,3] + gdp_noCovid_stl$time.series[,2])
var_seasonally <- var(gdp_noCovid_stl$time.series[,3] + gdp_noCovid_stl$time.series[,1])
- Trend
knitr::kable(max(0,1-(var_R/var_trend)), col.names = 'Forza del Trend')
| Forza del Trend |
|---|
| 0.995904 |
- Stagionalità
knitr::kable(max(0,1-(var_R/var_seasonally)), col.names = 'Forza della stagionalità')
| Forza della stagionalità |
|---|
| 0.7782484 |
Dando un valore reale alla forza delle due componenti siamo ancora più sicuri nel dire che la componente di trend sia la principale per la serie storica d’interesse. Entrambi gli indici sono vicini a 1, quindi anche la Stagionalità sembra influenzare la serie.
Modello di regressione lineare
Infine si stima un modello di regressione lineare assumendo come predittori le componenti della serie, in quanto legate alla struttura della serie storica di risposta.
- Gdp with Covid-19
mod1 <- tslm(gdp ~ trend + season, data = gdp_dat)
summary(mod1)
##
## Call:
## tslm(formula = gdp ~ trend + season, data = gdp_dat)
##
## Residuals:
## Min 1Q Median 3Q Max
## -107446 -9696 27 13809 28566
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 390628.97 5000.42 78.119 <2e-16 ***
## trend 1669.21 66.06 25.266 <2e-16 ***
## season2 -7332.01 5390.22 -1.360 0.1770
## season3 5666.15 5391.43 1.051 0.2959
## season4 14072.26 5393.46 2.609 0.0105 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 19060 on 95 degrees of freedom
## Multiple R-squared: 0.8746, Adjusted R-squared: 0.8693
## F-statistic: 165.6 on 4 and 95 DF, p-value: < 2.2e-16
Si notano inizialmente valori p-value alti per le stagionalità nel secondo e terzo trimestre ma, come sappiamo, è errato guardare la significatività delle variabili per capire se la serie è influenzata o meno dalle componenti.
In particolar modo la stagione 4 risulta avere valori particolarmente elevati rispetto alla stagionalità 1, catturata dall’intercetta. Il valore atteso del PIL nel quarto trimestre, infatti, aumenta di 14072 £ rispetto al primo trimestre.
Il p-value della statistica test F ci porta a rifiutare l’ipotesi \(H_{0}\), ovvero tutti i coefficienti pari a zero, ed a accettare, quindi, l’ipotesi alternativa \(H_{1}\), ovvero almeno un coefficiente è diverso da zero.
per quanto riguarda l’\(R^{2}\) possiamo dire che è molto simile all’\(R^{2}\) corretto, entrambi molto alti. Ricordiamo che l’\(R^{2}\) è l’indice che misura la proporzione di varianza spiegata dal modello; esso varia da 0 a 1 e piu è vicino a 1 più il modello considerato si adatta bene ai dati. In questo caso guardiamo maggiormente all’ \(R^{2}\) corretto poichè quest’ultimo non si lascia influenzare da variabili aggiunte o rimosse dal modello.
Analisi dei residui
Come ultima cosa eseguo un’analisi dei residui con il comando checkresiduals
checkresiduals(mod1)
##
## Breusch-Godfrey test for serial correlation of order up to 8
##
## data: Residuals from Linear regression model
## LM test = 46.098, df = 8, p-value = 2.277e-07
Dal correlogramma si nota una correlazione dei residui soltato per ritardi \(h = 1,2,3\), mentre per il resto dei residui, essi rientrano nell’intervallo di confidenza, pertanto sono incorrelati. Nonostante ciò non è così importante per far sì che il test di Breusch-Godfrey sia non significativo. Visto il bassissimo p-value, possiamo dire che l’alta correlazione nei primi ritardi ha un impatto notevole sulle previsioni o sugli intervalli di previsione.
A questo punto stimo un modello di regressione lineare considerando la serie storica non affetta da anomalie.
- GDP without Covid-19
mod2 <- tslm(gdp_noCovid ~ trend + season, data = gdp_dat)
summary(mod2)
##
## Call:
## tslm(formula = gdp_noCovid ~ trend + season, data = gdp_dat)
##
## Residuals:
## Min 1Q Median 3Q Max
## -20307.1 -10817.5 -464.4 9405.8 27864.1
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 386843.52 3256.32 118.798 < 2e-16 ***
## trend 1777.08 43.02 41.307 < 2e-16 ***
## season2 -4266.32 3510.15 -1.215 0.227217
## season3 5946.43 3510.95 1.694 0.093602 .
## season4 12843.58 3512.26 3.657 0.000419 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 12410 on 95 degrees of freedom
## Multiple R-squared: 0.9485, Adjusted R-squared: 0.9463
## F-statistic: 437.4 on 4 and 95 DF, p-value: < 2.2e-16
A differenza di prima il p-value associato alla stagionalità nel terzo trimestre è molto basso, per cui la variabile è statisticamente significativa.
C’è stato un aumento nell’\(R^{2}\) e \(R^{2}\) aggiustato.
Ancora una volta season2 porta una diminuzione nel valore atteso del GDP rispetto a season1, guardando il p-value della statistica test F, siamo portati nuovamente a rifiutare l’ipotesi \(H_{0}\).
Analisi dei residui
checkresiduals(mod2)
##
## Breusch-Godfrey test for serial correlation of order up to 8
##
## data: Residuals from Linear regression model
## LM test = 84.074, df = 8, p-value = 7.373e-15
shapiro.test(mod2$residuals)
##
## Shapiro-Wilk normality test
##
## data: mod2$residuals
## W = 0.9601, p-value = 0.00409
Rifiuto l’ipotesi di normalità dei residui. Essi inoltre sono ancora correlati tra loro.
Per risolvere questo problema potrei prendere in considerazione altre serie storiche così da ottenere un modello previsivo per il GDP migliore.
Predittori per il GDP britannico
L’obiettivo d’ora in avanti è analizzare l’impatto di altre misure macroeconomiche sul PIL britannico. In seguito sono riportare le serie storiche prese in analisi.
Real Imports of Goods and Services for Great Britain
Le importazioni possono influenzare il GDP di un paese in modo significativo. Esse sono definite come l’entrata di beni e servizi stranieri in un paese per l’uso o la distribuzione all’interno dei suoi confini nazionali. Le importazioni possono includere una vasta gamma di prodotti, come materie prime, prodotti manufatti, beni di consumo, macchinari, attrezzature, prodotti agricoli, servizi professionali e così via.
imp_dat <- read_excel("NMRNSAXDCGBQ.xls",
col_types = c("date", "numeric"), skip = 10)
imp <- ts(imp_dat$NMRNSAXDCGBQ,start = c(1998),frequency = 4)
Fonte:
International Monetary Fund, Real Imports of Goods and Services for Great Britain [NMRNSAXDCGBQ], retrieved from FRED, Federal Reserve Bank of St. Louis; https://fred.stlouisfed.org/series/NMRNSAXDCGBQ, June 20, 2023.
dyRangeSelector((dygraph(imp,
main = 'Real Imports of Goods and Services for Great Britain',
ylab = 'Domestic Currency(£)') %>%
dyEvent(c('2020-04-01','2009-04-01'),
c('Covid-19', 'Crisi Finanziaria'),
labelLoc ='bottom',strokePattern = 'dotted',color = 'red') %>%
dyEvent('2020-01-01','Brexit',labelLoc ='top',
strokePattern = 'dotted',color = 'red')))
Real Exports of Goods and Services for Great Britain
Le esportazioni rappresentano il processo mediante il quale un paese vende beni o servizi a altre nazioni. Sono un elemento fondamentale del commercio internazionale e riflettono la vendita di prodotti nazionali o servizi a consumatori, imprese o enti governativi di altri paesi.
Le esportazioni sono cruciali per l’economia di un paese poiché rappresentano una fonte di reddito e promuovono lo sviluppo economico coprendo la domanda estera.
exp_dat <- read_excel("NXRNSAXDCGBQ.xls",
col_types = c("date", "numeric"), skip = 10)
exp <- ts(exp_dat$NXRNSAXDCGBQ,start = c(1998),frequency = 4)
Fonte:
International Monetary Fund, Real Exports of Goods and Services for Great Britain [NXRNSAXDCGBQ], retrieved from FRED, Federal Reserve Bank of St. Louis; https://fred.stlouisfed.org/series/NXRNSAXDCGBQ, June 20, 2023.
dyRangeSelector((dygraph(exp,
main = 'Real Export of Goods and Services for Great Britain',
ylab = 'Domestic Currency(£)') %>%
dyEvent(c('2020-04-01','2009-04-01'),
c('Covid-19', 'Crisi Finanziaria'),
labelLoc ='bottom',strokePattern = 'dotted',color = 'red') %>%
dyEvent('2020-01-01','Brexit',labelLoc ='top',
strokePattern = 'dotted',color = 'red')))
Consumer Price Index: Total All Items for the United Kingdom
Il Consumer Price Index (CPI), o indice dei prezzi al consumo, è una misura statistica utilizzata per valutare i cambiamenti dei prezzi dei beni e dei servizi acquistati dai consumatori in un determinato periodo di tempo. Viene calcolato confrontando i prezzi dei beni e dei servizi nel periodo di riferimento con i prezzi di riferimento di un anno base specifico. L’indice tiene conto delle variazioni dei prezzi ponderando ciascuna componente del paniere sulla base della sua rilevanza nel budget dei consumatori.
È utilizzato come indicatore chiave dell’inflazione e fornisce informazioni importanti sulla variazione dei livelli dei prezzi nel tempo.
cpi_dat <- read_excel("CPALTT01GBQ657N.xls",
col_types = c("date", "numeric"), skip = 10)
cpi <- ts(cpi_dat$CPALTT01GBQ657N,start = c(1998),frequency = 4)
Fonte:
Organization for Economic Co-operation and Development, Consumer Price Index: Total All Items for the United Kingdom [CPALTT01GBQ657N], retrieved from FRED, Federal Reserve Bank of St. Louis; https://fred.stlouisfed.org/series/CPALTT01GBQ657N,June 19, 2023.
dyRangeSelector((dygraph(cpi,
main = 'Consumer Price Index: Total All Items for the United Kingdom') %>%
dyEvent(c('2020-04-01','2009-04-01'),
c('Covid-19', 'Crisi'),
labelLoc ='bottom',strokePattern = 'dotted',color = 'red') %>%
dyEvent('2020-01-01','Brexit',labelLoc ='top',
strokePattern = 'dotted',color = 'red')))
Active Population for the United Kingdom (Aged 15-64)
Collegandomi a quanto detto nel paragrafo dedicato alla Brexit, quest’ultima ha reso più difficile per alcune aziende trovare lavoratori. Una delle principali cause è legata al fatto che i lavoratori non si sentono più tutelati dalle leggi emanate dall’Unione europea per quanto riguarda la Sicurezza sul lavoro. Ciò ha portato il governo, in un primo tempo, a permettere l’allungamento degli orari di lavoro. Per questo motivo gli imprenditori chiedono l’intervento del governo perchè il Regno Unito riapra le porte ai lavoratori stranieri.
empl_dat <- read_excel("LFAC64TTGBQ647N.xls",
col_types = c("date", "numeric"), skip = 10)
empl <- ts(empl_dat$LFAC64TTGBQ647N,start = c(1998),frequency = 4)
Fonte:
Organization for Economic Co-operation and Development, Active Population: Aged 15-64: All Persons for the United Kingdom [LFAC64TTGBQ647N], retrieved from FRED, Federal Reserve Bank of St. Louis; https://fred.stlouisfed.org/series/LFAC64TTGBQ647N,June 22, 2023. https://www.internazionale.it/opinione/roberta-carlini/2021/09/01/brexit-pandemia-lavoro-immigrati
dyRangeSelector((dygraph(empl,
main = 'Active Population for the United Kingdom (Aged 15-64)') %>%
dyEvent(c('2020-04-01','2009-04-01'),
c('Covid-19', 'Crisi'),
labelLoc ='bottom',strokePattern = 'dotted',color = 'red') %>%
dyEvent('2020-01-01','Brexit',labelLoc ='top',
strokePattern = 'dotted',color = 'red')))
Real Private Sector Final Consumption Expenditure for Great Britain
Indicatore economico che misura la spesa finale di consumo del settore privato nel Regno Unito per l’acquisto di beni e servizi destinati al consumo finale.
pce_dat <- read_excel("NCPRNSAXDCGBQ.xls",
col_types = c("date", "numeric"), skip = 10)
pce <- ts(pce_dat$NCPRNSAXDCGBQ,start = c(1998),frequency = 4)
Fonte:
International Monetary Fund, Real Private Sector Final Consumption Expenditure for Great Britain [NCPRNSAXDCGBQ], retrieved from FRED, Federal Reserve Bank of St. Louis; https://fred.stlouisfed.org/series/NCPRNSAXDCGBQ, June 20, 2023.
dyRangeSelector((dygraph(exp,
main = 'Real Private Sector Final Consumption Expenditure for Great Britain',
ylab = 'Domestic Currency(£)') %>%
dyEvent(c('2020-07-01','2009-01-01'),
c('Covid-19', 'Crisi Finanziaria'),
labelLoc ='bottom',strokePattern = 'dotted',color = 'red') %>%
dyEvent('2020-01-01','Brexit',labelLoc ='top',
strokePattern = 'dotted',color = 'red')))
Real General Government Final Consumption Expenditure for Great Britain
Indicatore economico che misura la spesa finale di consumo del settore pubblico e amministrativo nel Regno Unito per l’acquisto di beni e servizi destinati al consumo finale.
gce_dat <- read_excel("NCGGRNSAXDCGBQ.xls",
col_types = c("date", "numeric"), skip = 10)
gce <- ts(gce_dat$NCGGRNSAXDCGBQ,start = c(1998),frequency = 4)
Fonte:
International Monetary Fund, Real General Government Final Consumption Expenditure for Great Britain [NCGGRNSAXDCGBQ], retrieved from FRED, Federal Reserve Bank of St. Louis; https://fred.stlouisfed.org/series/NCGGRNSAXDCGBQ ,June 22, 2023.
dyRangeSelector((dygraph(gce,
main = 'Real General Government Final Consumption Expenditure for Great Britain',
ylab = 'Domestic Currency(£)') %>%
dyEvent(c('2020-04-01','2009-04-01'),
c('Covid-19', 'Crisi Finanziaria'),
labelLoc ='bottom',strokePattern = 'dotted',color = 'red') %>%
dyEvent('2020-09-01','Brexit',labelLoc ='top',
strokePattern = 'dotted',color = 'red')))
Real Residential Property Prices for United Kingdom
Come ultima serie storica, ho scelto di analizzare un indicatore economico che rappresenta il valore delle proprietà residenziali al netto dell’effetto dell’aumento generale dei prezzi nel tempo. Real in quanto sono tenuti conto dell’inflazione, cosi come tutte le altre serie storiche in analisi.
Un PIL in crescita è spesso associato a una maggiore attività economica, creazione di posti di lavoro e aumento del reddito delle persone. Ciò può aumentare la domanda di proprietà residenziali, poiché le persone hanno maggiori risorse finanziarie per acquistare una casa o investire nel settore immobiliare.
Un PIL più elevato può favorire un clima economico più stabile e un maggiore accesso al credito da parte delle istituzioni finanziarie. Ciò può rendere più facile per le persone ottenere finanziamenti per l’acquisto di proprietà residenziali, aumentando così la domanda e potenzialmente influenzando al rialzo i prezzi delle case.
rpp_dat <- read_excel("QGBR368BIS.xls",
col_types = c("date", "numeric"), skip = 10)
rpp <- ts(rpp_dat$QGBR368BIS,start = c(1998),frequency = 4)
Fonte:
Bank for International Settlements, Real Residential Property Prices for United Kingdom [QGBR368BIS], retrieved from FRED, Federal Reserve Bank of St. Louis; https://fred.stlouisfed.org/series/QGBR368BIS, June 20, 2023.
dyRangeSelector((dygraph(rpp,
main = 'Real Residential Property Prices for United Kingdom')%>%
dyEvent('2009-01-01','Crisi Finanziaria',
labelLoc ='bottom',strokePattern = 'dotted',color = 'red')))
GDP in funzione dei predittori
Una volta introdotte le altre serie storiche che fungeranno da predittori per il modello completo, procedo con la creazione del dataset.
Dataset
gdp_dat2 <-cbind(gdp,imp,exp,cpi,empl,pce,gce,rpp)
autoplot(gdp_dat2, facets = TRUE)
knitr::kable(summary(gdp_dat2))
| gdp | imp | exp | cpi | empl | pce | gce | rpp | |
|---|---|---|---|---|---|---|---|---|
| Min. :372145 | Min. : 77662 | Min. : 88301 | Min. :-0.6000 | Min. :27923000 | Min. :221503 | Min. : 68577 | Min. :-17.8993 | |
| 1st Qu.:441938 | 1st Qu.:115946 | 1st Qu.:110634 | 1st Qu.: 0.1336 | 1st Qu.:29363750 | 1st Qu.:281178 | 1st Qu.: 86373 | 1st Qu.: 0.1464 | |
| Median :476946 | Median :139024 | Median :138896 | Median : 0.4796 | Median :30930500 | Median :299822 | Median : 95231 | Median : 4.5966 | |
| Mean :478025 | Mean :138311 | Mean :135440 | Mean : 0.5731 | Mean :30766170 | Mean :301955 | Mean : 93092 | Mean : 4.0624 | |
| 3rd Qu.:520796 | 3rd Qu.:163743 | 3rd Qu.:152139 | 3rd Qu.: 0.9232 | 3rd Qu.:32207000 | 3rd Qu.:331344 | 3rd Qu.:100924 | 3rd Qu.: 7.7439 | |
| Max. :579989 | Max. :194452 | Max. :191269 | Max. : 3.6364 | Max. :32921000 | Max. :370160 | Max. :116208 | Max. : 23.3702 |
Le serie storiche hanno unità di misure differenti, ricordiamolo per l’analisi futura.
Per prima cosa controllo la collinearità tra i predittori
ggpairs(as.data.frame(gdp_dat2))
Guardando ai valori vi è in generale una fortissima correlazione tra le serie storiche, ma attraverso l’autoplot delle serie notiamo che tutte sono influenzate da un trend crescente, il quale determina l’effetto sulla correlazione.
Per rimuovere l’effetto del trend possiamo applicare le differenze con ritardo 1 per tutte le serie e confrontarle.
gdp_dat2_nocor <- diff(gdp_dat2[,-1])
ggpairs(as.data.frame(gdp_dat2_nocor))
notiamo infatti una bassa correlazione tra i predittori.
Modello di regressione lineare multiplo
a questo punto stimo un modello di regressione lineare multiplo, inserendo tutte le serie storiche analizzate.
\[ y_{i}=\beta_{0}+\beta_{1}imp+\beta_{2}exp+\beta_{3}cpi+\beta_{4}empl+\beta_{5}pce+\beta_{6}gpe+\beta_{7}rpp+\beta_{8}trend+\beta_{9}season \]
mod.full <- tslm(gdp ~ imp + exp + cpi + empl + pce + gce + rpp + trend + season,
data = gdp_dat2)
summary(mod.full)
##
## Call:
## tslm(formula = gdp ~ imp + exp + cpi + empl + pce + gce + rpp +
## trend + season, data = gdp_dat2)
##
## Residuals:
## Min 1Q Median 3Q Max
## -10187 -2194 324 2779 9829
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.767e+05 9.646e+04 1.832 0.070352 .
## imp -3.515e-02 1.072e-01 -0.328 0.743747
## exp 4.739e-01 9.604e-02 4.934 3.78e-06 ***
## cpi 1.072e+03 1.360e+03 0.788 0.432746
## empl -3.820e-03 3.613e-03 -1.057 0.293291
## pce 9.977e-01 7.233e-02 13.795 < 2e-16 ***
## gce 5.764e-01 1.696e-01 3.398 0.001021 **
## rpp 2.711e+02 1.065e+02 2.545 0.012681 *
## trend 1.939e+02 1.562e+02 1.241 0.217760
## season2 -1.353e+04 1.876e+03 -7.211 1.84e-10 ***
## season3 -7.207e+03 1.742e+03 -4.137 8.04e-05 ***
## season4 -6.871e+03 1.856e+03 -3.701 0.000374 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 4700 on 88 degrees of freedom
## Multiple R-squared: 0.9929, Adjusted R-squared: 0.992
## F-statistic: 1124 on 11 and 88 DF, p-value: < 2.2e-16
Si nota innanzitutto un altissimo valore dell’\(R^{2}\) e \(R^{2}\) aggiustato, entrambi molto simili tra loro.
le uniche variabili a non essere statisticamente significative sono imp (Importazioni), cpi(Consumer Price Index) e empl(numero di lavoratori).
il p-value della F-statistic ci porta a rifiutare l’ipotesi \(H_{0}\) di nullità di tutti i predittori
per quanto riguarda le variabili statisticamente significative, tutte portano a un aumento nel valore atteso del GDP britannico.
Non ci resta che analizzare i residui
Analisi dei residui
checkresiduals(mod.full)
##
## Breusch-Godfrey test for serial correlation of order up to 15
##
## data: Residuals from Linear regression model
## LM test = 41.304, df = 15, p-value = 0.0002874
I residui mostrano un’elevata eteroschedasticità, cosi come il p-value, molto basso, ci porta a rifiutare l’ipotesi nulla \(H_{0}\) del test di Breusch e Godfrey per qualsiasi valore di \(\alpha\). Ricordiamo però che la correlazione nei residui non rende le previsioni distorte, quindi queste non sono sbagliate, rende solo gli intervalli di previsione più ampi e quindi la stima più incerta.
Verifichiamo la normalità dei residui attraverso lo shapiro test
shapiro.test(mod.full$residuals)
##
## Shapiro-Wilk normality test
##
## data: mod.full$residuals
## W = 0.97824, p-value = 0.09692
p-value alto, non rifiuto a priori \(H_{0}\), per tanto la distribuzione dei residui può essere approssimata ad una normale.
Infine, eseguo un plot dei residui.
Vogliamo che i nostri residui non mostrino alcun pattern ma, al contrario, siano abbastanza sparsi. Prendo in considerazione solo lo scatter con le variabili statisticamente significative.
df <- data.frame(gdp_dat2)
df[,"Residuals"] <- as.numeric(residuals(mod.full))
p1 <- ggplot(df, aes(x=exp, y=Residuals)) +
geom_point()
p2 <- ggplot(df, aes(x=pce, y=Residuals)) +
geom_point()
p3 <- ggplot(df, aes(x=gce, y=Residuals)) +
geom_point()
p4 <- ggplot(df, aes(x=rpp, y=Residuals)) +
geom_point()
gridExtra::grid.arrange(p1, p2, p3, p4,nrow=2)
I residui sembrano essere randomly scattered.
Confronto tra modelli
Provo a stimare un altro modello andando a togliere le variabili statisticamente non significative, lascio il trend che è la componente principale delle serie storiche.
mod.full2 <- tslm(gdp ~ exp + pce + gce + rpp + trend + season,
data = gdp_dat2)
summary(mod.full2)
##
## Call:
## tslm(formula = gdp ~ exp + pce + gce + rpp + trend + season,
## data = gdp_dat2)
##
## Residuals:
## Min 1Q Median 3Q Max
## -10463.2 -2614.5 650.9 2846.2 11148.8
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 7.313e+04 1.004e+04 7.284 1.13e-10 ***
## exp 4.553e-01 8.036e-02 5.666 1.70e-07 ***
## pce 9.449e-01 5.528e-02 17.092 < 2e-16 ***
## gce 6.639e-01 1.579e-01 4.205 6.11e-05 ***
## rpp 3.348e+02 8.511e+01 3.933 0.000164 ***
## trend 1.935e+01 6.019e+01 0.322 0.748559
## season2 -1.195e+04 1.421e+03 -8.406 5.50e-13 ***
## season3 -7.180e+03 1.540e+03 -4.661 1.07e-05 ***
## season4 -5.792e+03 1.540e+03 -3.760 0.000300 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 4739 on 91 degrees of freedom
## Multiple R-squared: 0.9926, Adjusted R-squared: 0.9919
## F-statistic: 1520 on 8 and 91 DF, p-value: < 2.2e-16
procedo con l’analisi dei residui
checkresiduals(mod.full2)
##
## Breusch-Godfrey test for serial correlation of order up to 12
##
## data: Residuals from Linear regression model
## LM test = 37.371, df = 12, p-value = 0.0001944
anche in questo caso notiamo dei residui fortemente eteroschedastici e il p-value del test ancora troppo basso da poter accettare l’ipotesi \(H_{0}\). Nonostante ciò, il correlogramma ci mostra un’alta correlazione tra il secondo e quarto ritardo della serie dei residui, mentre per altri valori di h le autocorrelazioni sembrano essere statisticamente non significative.
confrontiamo i due modelli con i criteri di validazione
CV_mod.full <-data.frame(t(CV(mod.full)))
rownames(CV_mod.full)="mod.full"
CV_mod.full2 <-data.frame(t(CV(mod.full2)))
rownames(CV_mod.full2)="mod.full2"
knitr::kable(rbind(CV_mod.full,CV_mod.full2))
| CV | AIC | AICc | BIC | AdjR2 | |
|---|---|---|---|---|---|
| mod.full | 27639492 | 1704.289 | 1708.522 | 1738.156 | 0.9920498 |
| mod.full2 | 27055227 | 1703.289 | 1705.761 | 1729.340 | 0.9919177 |
I criteri di validazione preferiscono il modello ridotto (mod.full2) in quanto ha sia valori di AIC, che di BIC piu bassi rispetto al modello completo.
Eseguo un test F per il confronto tra due modelli.
anova(mod.full,mod.full2)
## Analysis of Variance Table
##
## Model 1: gdp ~ imp + exp + cpi + empl + pce + gce + rpp + trend + season
## Model 2: gdp ~ exp + pce + gce + rpp + trend + season
## Res.Df RSS Df Sum of Sq F Pr(>F)
## 1 88 1944094687
## 2 91 2043760390 -3 -99665703 1.5038 0.2191
anche in questo caso il p-value è alto da poter rifiutare \(H_{0}\), pertanto si sceglie ancora il modello ridotto.
Adesso verifico l’incorrelazione tra i residui e i predittori
cor_res_pred<-rbind(cor(df["exp"],df["Residuals"]),
cor(df["pce"],df["Residuals"]),
cor(df["gce"],df["Residuals"]),
cor(df["rpp"],df["Residuals"]))
as.data.frame(cor_res_pred)
## Residuals
## exp -1.121791e-17
## pce -3.542999e-18
## gce -3.759994e-17
## rpp 1.568799e-17
Ulteriore prova che il modello considerato è un ottimo modello, adesso verifichiamo l’incorrelazione con la serie storica di risposta
cor_res_gdp<-rbind(cor(df["gdp"],df["Residuals"]))
knitr::kable(cor_res_gdp)
| Residuals | |
|---|---|
| gdp | 0.0840646 |
Anche in questo caso la correlaizone è bassa.
Utilizzo il modello ridotto per le previsioni.
Previsioni
L’ultimo paragrafo di questo progetto è dedicato alle previsioni.
Siccome la presenza di valori anomali, dovuti soprattuto al Covid-19 e, nello stesso periodo, alla Brexit influiscono sulle capacità predittive dei modelli, quest’ultimi verrano addestrati sulle osservazioni dal 1998 al 2018 e testati sulle osservazioni dal 2019 al 2022 della serie storica senza anomalie gdp_noCovid.
Prima di prendere in considerazione il modello di regressione inizio le previsioni attraverso i modelli di benchmark.
Modelli di benchmark
I modelli di previsione benchmark sono modelli utilizzati come punto di riferimento o standard di confronto per valutare le prestazioni di altri modelli di previsione più complessi.
Avarage method :
utilizza la media storica dei dati passati come base per le previsioni future. Questo metodo, sebbene sia il più semplice, non tiene conto di eventuali tendenze, stagionalità o modelli complessi nei dati, ma si bassa sull’assunzione che i valori futuri saranno simili alla media dei valori passati.
\(y_{T+h|T} = \frac{\sum_{t = 1}^{T} y_{t}}{T}\)
Naïve method :
si basa sull’assunzione che il valore futuro sarà uguale all’ultimo valore osservato. Anch’esso non tiene conto di alcuna tendenza, stagionalità ed è particolarmente utile quando si prevede che il valore futuro sia influenzato solo dal valore attuale.
\(y_{T+h|T} = y_{T}\)
Seasonal Naïve method :
variante del Naïve method che tiene conto della stagionalità dei dati nella previsione. Questo modello, infatti, si basa sull’assunzione che il valore futuro sarà uguale al valore osservato corrispondente allo stesso periodo dell’anno precedente (in questo caso parliamo di trimestre).
\(y_{T+h|T} = y_{T+h-m(k+1)}\)
Drift method :
metodo di previsione che tiene conto del trend nei dati per generare preivsioni future. Questo metodo si basa sull’assunzione che il valore futuro sarà influenzato da una crescita o da una diminuzione costante nel tempo, nota appunto come “drift” o “trend”.
\(y_{T+h|T} = y_{T} + h \frac{y_{T} - y{_1}}{T-1}\)
ottengo quindi il train e il test
train <- window(gdp, start = 1998, end = c(2018,4))
test <- window(gdp_noCovid,start = 2019, end = c(2022,4))
addestro i quattro modelli sul train \(h = 16\) perchè voglio prevedere dal primo trimestre del 2019 al quarto trimestre del 2022.
mean_fit <- meanf(train, 16)
naive_fit <- naive(train, 16)
snaive_fit <- snaive(train, h=16)
drift_fit <- rwf(train, 16, drift=TRUE)
verifica empirica delle previsioni eseguite con i diversi metodi
autoplot(gdp_noCovid) +
autolayer(mean_fit, series="Mean", PI=FALSE) +
autolayer(naive_fit, series="Naïve", PI=FALSE) +
autolayer(snaive_fit, series="Seasonal Naïve", PI=FALSE) +
autolayer(drift_fit, series="Drift", PI=FALSE) +
xlab("Year") +
ylab("Currency (£)") +
ggtitle("Real Gross Domestic Product for Great Britain") +
guides(colour=guide_legend(title="Forecast"))
Dal punto di vista empirico il Seasonal Naive sembra cogliere meglio l’andamento della serie storica rispetto agli altri metodi utilizzati.
Confrontiamo le misure di accuratezza sul test.
knitr::kable(rbind(
"Average" = accuracy(mean_fit, test)[2,c(2,3,5,6)],
"Naïve" = accuracy(naive_fit, test)[2,c(2,3,5,6)],
"Seasonal Naïve" = accuracy(snaive_fit, test)[2,c(2,3,5,6)],
"Drift" = accuracy(drift_fit, test)[2,c(2,3,5,6)]))
| RMSE | MAE | MAPE | MASE | |
|---|---|---|---|---|
| Average | 85442.999 | 84733.043 | 15.333584 | 7.4125823 |
| Naïve | 19011.154 | 16508.243 | 3.028409 | 1.4441675 |
| Seasonal Naïve | 7426.096 | 6569.993 | 1.195362 | 0.5747535 |
| Drift | 38015.189 | 35414.499 | 6.457605 | 3.0981171 |
Il seasonal naive sembra essere il metodo prescelto in quanto mostra un tasso di errore più basso, nonostante ciò, esso non riesce a catturare il trend della serie. Ciò lo notiamo dalla previsione che non risulta essere in crescita con l’andamento dell’intera serie storica; l’unico metodo capace di cogliere la componente principale della serie è il Drift.
Eseguo, quindi, un’analisi dei residui solo per il metodo Seasonal Naive per verificare se il modello rispetta i requisiti per essere giudicato un buon modello
- Analisi dei residui
checkresiduals(snaive_fit)
##
## Ljung-Box test
##
## data: Residuals from Seasonal naive method
## Q* = 90.27, df = 8, p-value = 4.441e-16
##
## Model df: 0. Total lags used: 8
guardando alla distribuzione possiamo dire che i residui presentano un minimo di struttura, in quanto solo poche osservazioni non oscillano intorno a un valore medio costante, come per esempio il picco intorno al 2010 sicuramente influenzato da valori anomali (possibile effetto della crisi finanziaria).
Guardando al correlogramma, soltanto le autocorrelazioni ai primi due ritardi sembrano essere statisticamente significative e ciò ci porta a rifiutare l’ipotesi \(H_{0}\) del test di Ljung-Box, ovvero tutte le autocorrelazioni sono uguali a zero.
Modello di previsione
A questo punto non ci resta che utilizzare il modello ridotto mod.full2 per le previsioni e per valutare la bontà previsiva del modello.
Siccome nessun modello è capace di prevedere il Gdp durante la pandemia globale, decido di fermarmi prima con le osservazioni.
- Train dal primo trimestre del 1998 al quarto trimestre del 2014
train_prev <- ts(df[1:68,], start = 1998,frequency = 4)
- Test dal primo trimestre del 2015 al quarto del 2018
test_prev <- as.data.frame(ts(df[69:84,],start = 2015, frequency = 4))
considero, dunque, i predittori del modello ridotto mod.full2.
mod_prev <- tslm(gdp ~ exp + pce + gce + rpp + trend + season,
data = train_prev)
forecast_mod <- forecast(mod_prev, test_prev)
visualizziamo le previsioni
gdp_ridotto <- window(gdp, start = 1998, end = c(2018,4))
autoplot(gdp_ridotto) +
autolayer(forecast_mod, series="Forecast", PI=FALSE) +
xlab("Year") +
ylab("Currency (£)") +
ggtitle("Real Gross Domestic Product for Great Britain")
Possiamo notare che le previsioni sovrastimano leggermente i valori del Gdp. Confrontiamo le misure di accuratezza previsive.
accuracy(forecast_mod, test_prev)[2,c(2,3,5,6)]
## RMSE MAE MAPE MASE
## 7024.1269800 5290.2963735 0.9857395 0.6138478